//
//  WeatherListViewModel.swift
//  Weather
//
//  Created by jingjing jia on 2023/4/27.
//

import Combine
import Foundation
import SwiftUI

class WeatherListViewModel: ObservableObject {
    
    @Published var isLoading: Bool = false
    @Published var lives: [WeatherHeaderViewModel] = []
    @Published var forecasts: [WeatherDetailViewModel] = []
    
    var choosedCity: CityModel?
    var cities: [CityModel] = []
    
    private var webRepository: RealWeatherWebRepository!
    private var subscriptions = Set<AnyCancellable>()
    
    init() {
        subscriptions = Set<AnyCancellable>()
        webRepository = RealWeatherWebRepository(session: NetworkingHelpers.configuredURLSession(), baseURL: NetworkingHelpers.baseURL)

        loadCities()
    }
    
    func fetchWeatherLive()  {
        if let city = self.choosedCity {
            webRepository.fetchLiveWeather(city: city)
                .sinkToResult { [weak self] result in
                    
                    guard let self = self else { return }

                    switch result {
                    case .success(let weather):
                        if weather.lives.first != nil {
                            self.lives = weather.lives.map { WeatherHeaderViewModel(live: $0) }
                        } else {
                            // Code to handle nil value
                        }
                    case .failure(let error):
                        print("Error fetching weather: \(error)")
                    }
                    self.isLoading = false
                }
                .store(in: &subscriptions)
        }
    }
    
    func fetchWeatherForecase()  {
        if let city = self.choosedCity {
            webRepository.fetchForecastWeather(city: city)
                .sinkToResult { [weak self] result in
                    
                    guard let self = self else { return }

                    switch result {
                    case .success(let weather):
                        if let firstForecast = weather.forecasts.first {
                            self.forecasts = firstForecast.casts.map { WeatherDetailViewModel(forecast: $0) }
                        } else {
                            // Code to handle nil value
                        }
                    case .failure(let error):
                        print("Error fetching weather: \(error)")
                    }
                    self.isLoading = false
                }
                .store(in: &subscriptions)
        }
    }
    
    private func loadCities() {
        if let data = FileHelper.loadBundledJSON("City") as? Data,
           let cities = try? JSONDecoder().decode([CityModel].self, from: data ) {
            self.cities = cities
            self.choosedCity = cities.first
            
            fetchWeatherLive()
            fetchWeatherForecase()
        }
    }
    
    private var requestHoldBackTimeInterval: TimeInterval {
        return ProcessInfo.processInfo.isRunningTests ? 0 : 0.5
    }
    
}

extension ProcessInfo {
    var isRunningTests: Bool {
        environment["XCTestConfigurationFilePath"] != nil
    }
}
